package ec.fugu.samples;

/**
 * NetworkThread
 * 
 * This is just a Thread which the Main UI must wait for.
 * 
 * In most applications this will be a networking Thread
 * so this sample has been designed to simulate that.
 * It is created with a URL and returns a byte array.
 * But this general 'pattern' applies anywhere the UI needs to wait.
 *
 */


public class NetworkThread extends Thread {

    private ObserverInterface _ourObserver;
    private boolean _stopRequest = false;

    public NetworkThread(String requestURL, ObserverInterface observer) {
        super();
        _ourObserver = observer;
    }

    /**
     * stop is called if the processing should not continue.
     */
    public void stop() {
        // Tell our observer
        observerError(ObserverInterface.CANCELLED, "Cancelled by User");
        _stopRequest = true; // Will no longer tell Observer anything
        this.interrupt(); // Give our Thread a kick
    }

    private void observerStatusUpdate(final int status, final String statusString) {
        if ( !_stopRequest ) {
            _ourObserver.processStatusUpdate(status, statusString);
        }
    }

    private void observerError(int errorCode, String errorMessage) {
        if ( !_stopRequest ) {
            _ourObserver.processError(errorCode, errorMessage);
        }
    }

    private void observerResponse(byte [] reply) {
        if ( !_stopRequest ) {
            _ourObserver.processResponse(reply);
        }
    }

    /**
     * Process the long running or blocking operation in this Thread
     * Update the Observer as required using
     * - processStatus, whenever desired
     * and then one of:
     * - processError, if there was a problem
     * - processResponse, if the data was obtained OK
     */
    public void run () {

        // Following are just test variables, hopefully self eplanatory
        long stallTime = 10000; // Will stall for this time
        boolean willFail = false; // false - will finshed OK, true - will fail!
        long updateInterval = 1000; // Update Observer every second
        long startTime = System.currentTimeMillis();
        long finishTime = startTime + stallTime;
        long currentTime = startTime;

        observerStatusUpdate(1, "Started"); // Tell user we have started

        if ( willFail ) {
            // Fail 1/2 way through
            finishTime = startTime + stallTime / 2;
        }

        while ( !_stopRequest &&
                currentTime < finishTime ) {
            // THis just simulates the fact that we can update the Observer (Ui) from time to time
            try {
                Thread.sleep(updateInterval);
            } catch (Exception e) {
            }
            // Calculate a percentage to tel the Observer
            currentTime = System.currentTimeMillis();
            int percentageFinished = (int) (((currentTime - startTime) * 100l) / stallTime);
            percentageFinished = Math.min(percentageFinished, 99); // Just so we don't exceed guage value.
            observerStatusUpdate(percentageFinished, "Processing: " + Integer.toString(percentageFinished));
        }

        observerStatusUpdate(100, "Finished"); // Tell Observer we have finished

        //  Did we finish OK or badly
        if ( willFail ) {
            observerError(ObserverInterface.ERROR, "Failed");
        } else {
            observerResponse("Succeeded".getBytes());
        }

        // Make sure we do nothing else
        _stopRequest = true;
        _ourObserver = null;
    }

}